<?php

namespace app\product\service;

use app\common\library\Service;
use think\Hook;

class ProductOrder extends Service
{
    use \app\common\library\traits\Model;

    protected $model = null;

    protected function _initialize()
    {
        parent::_initialize();
        $this->model = model('product/product_order');
    }

    /**
     * 撤掉申请
     * @param string         $sn
     * @param bool | integer $user_id
     * @return bool
     */
    public function cancel($sn, $user_id = false)
    {
        $maps = ['sn' => $sn];
        if ($user_id !== false) {
            $maps['customer_id'] = $user_id;
        }
        $order = $this->model->where($maps)->find();

        if (!$order) {
            $this->error = "订单不存在";
            return false;
        }

        if ($order['status'] !== 0) {
            $this->error = '订单状态异常';
            return false;
        }

        $order['status'] = -1;
        \think\Db::startTrans();
        $result = $this->save($order, ['sn' => $sn], 'cancel');
        if (!$result) {
            $this->error = $this->getError();
            return false;
        }

        // 写入订单追踪
        $trace = model('product/product_order_trace', 'service')->create($sn, $user_id, '撤销申请');
        if (!$trace) {
            \think\Db::rollback();
            $this->error = model('product/product_order_trace', 'service')->getError();
            return false;
        }
        \think\Hook::listen("ProductOrderCancelAfter", $result);
        \think\Db::commit();
        return $result;
    }

    /**
     * 邀请/分享 表单
     * 本操作会跳过初核，申请成功后会立即准备资料
     * @param integer $user_id             用户ID
     * @param string  $realname            姓名
     * @param string  $mobile              手机号
     * @param integer $profile_template_id 资料清单ID
     * @return boolean
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function invite($user_id, $realname, $mobile, $profile_template_id)
    {
        $user = model('user/user', 'service')->where([
            'id'     => $user_id,
            'status' => 1,
            'role'   => ['neq', 2],
        ])->find();
        if (!$user) {
            $this->error = '用户身份异常';
            return false;
        }

        $profile_template = model('product/profile_template')
            ->where(['id' => $profile_template_id])
            ->find();

        if (!$profile_template) {
            $this->error = "资料清单有误";
            return false;
        }

        $product = $profile_template->product;

        $info = [
            'uid'                  => $user_id,
            'product_id'           => $profile_template['product_id'],
            'sn'                   => 'D' . date('YmdHis') . \fast\Random::build('numeric', 6),
            'question_template_id' => 0,
            'question_result_id'   => 0,
            'profile_template_id'  => $profile_template_id,
            'customer_id'          => (int)$profile_template['owner_aid'],
            'customer_point'       => (int)$product['customer_point'],
            'distributor_id'       => (int)$user['distributor_id'],
            'distributor_point'    => (int)$product['distributor_point'],
            'realname'             => (string)$realname,
            'mobile'               => (string)$mobile,
            'status'               => 0,
            'stage'                => 3,
        ];

        \think\Db::startTrans();
        $result = $this->save($info, [], 'add');
        if (!$result) {
            \think\Db::rollback();
            $this->error = $this->getError();
            return false;
        }

        // 写入订单跟踪日志
        $trace = model('product/product_order_trace', 'service')->create($result['sn'], $result['uid'], 'service.stage.3');
        if (!$trace) {
            \think\Db::rollback();
            $this->error = model('product/product_order_trace', 'service')->getError();
            return false;
        }

        // 更新贷款次数
        $user_product_num = model('user/user')->where('id', '=', $user_id)->setInc('product_num');
        if (!$user_product_num) {
            \think\Db::rollback();
            $this->error = '系统异常';
            return false;
        }

        \think\Hook::listen("ProductOrderApplyAfter", $result);
        \think\Db::commit();
        return $result;
    }

    /**
     * 申请贷款
     * @param       $user_id      integer     用户ID
     * @param       $product_id   integer     产品ID
     * @param array $question     array       初核问答
     * @param       $realname     string 姓名
     * @param       $mobile       string 手机号码
     * @return boolean
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function apply($user_id, $product_id, $question = [], $realname, $mobile)
    {
        $user = model('user/user')->find($user_id);
        if (!$user) {
            $this->error = '用户不存在';
            return false;
        }

        if ($user['status'] != 1) {
            $this->error = '用户已被锁定';
            return false;
        }

        if ($user['role'] == 2) {
            $this->error = '您当前的身份为客户经理，赞不开放贷款申请通道';
            return false;
        }

        $product = model('product/product')->find($product_id);
        if (!$product || $product['status'] == 0) {
            $this->error = '产品不存在或已下架';
            return false;
        }
        \think\Db::startTrans();
        $question_result = model('product/question_result', 'service')->create($user, $product, $question);
        if (!$question_result) {
            \think\Db::rollback();
            $this->error = model('product/question_result', 'service')->getError();
            return false;
        }

        $info = [
            'uid'                  => $user_id,
            'product_id'           => $product_id,
            'sn'                   => 'D' . date('YmdHis') . \fast\Random::build('numeric', 6),
            'question_template_id' => (int)$product['question_template_id'],
            'question_result_id'   => (int)$question_result['id'],
            'profile_template_id'  => (int)$product['profile_template_id'],
            'customer_id'          => (int)$user['customer_id'],
            'customer_point'       => (int)$product['customer_point'],
            'distributor_id'       => (int)$user['distributor_id'],
            'distributor_point'    => (int)$product['distributor_point'],
            'realname'             => (string)$realname,
            'mobile'               => (string)$mobile
        ];

        if ($question_result['result'] == 1) {
            $info['stage'] = 0;
        } else {
            $info['stage'] = -1;
            $info['status'] = 1;
        }


        $result = $this->save($info, [], 'add');
        if (!$result) {
            $this->error = $this->getError();
            \think\Db::rollback();
            return false;
        }

        // 写入订单跟踪日志
        $trace = model('product/product_order_trace', 'service')->create($result['sn'], $result['uid'], 'service.stage.' . $info['stage']);
        if (!$trace) {
            \think\Db::rollback();
            $this->error = model('product/product_order_trace', 'service')->getError();
            return false;
        }

        $user_product_num = model('user/user')->where('id', '=', $user_id)->setInc('product_num');
        if (!$user_product_num) {
            \think\Db::rollback();
            $this->error = '系统异常';
            return false;
        }

        \think\Hook::listen("ProductOrderApplyAfter", $result);
        \think\Db::commit();
        return $result;
    }

    /**
     * 客户经理首次联系
     * @param string  $sn      订单号
     * @param boolean $user_id 会员ID
     * @return bool
     */
    public function contact($sn, $user_id = false)
    {
        $maps = ['sn' => $sn];
        if ($user_id !== false) {
            $maps['customer_id'] = $user_id;
        }
        $order = $this->model->where($maps)->find();

        if (!$order) {
            $this->error = "订单不存在";
            return false;
        }

        if ($order['status'] !== 0 || $order['stage'] !== 0) {
            $this->error = '订单状态异常';
            return false;
        }
        // 获取订单用户
        $order->stage = 1;
        \think\Db::startTrans();
        $result = $order->save($order, ['sn' => $sn], 'contact');
        if (!$result) {
            $this->error = $this->getError();
            return false;
        }

        // 写入订单追踪
        $trace = model('product/product_order_trace', 'service')->create($sn, $user_id, 'service.stage.1');
        if (!$trace) {
            \think\Db::rollback();
            $this->error = model('product/product_order_trace', 'service')->getError();
            return false;
        }
        \think\Hook::listen("ProductOrderContactAfter", $order);
        \think\Db::commit();
        return $order;
    }

    /**
     * 客户确认首次联系
     * @param string $sn 订单号
     * @param bool   $user_id
     * @return bool
     */
    public function confirm($sn, $user_id = false)
    {
        $maps = ['sn' => $sn];
        if ($user_id !== false) {
            $maps['uid'] = $user_id;
        }
        $order = $this->model->where($maps)->find();

        if (!$order) {
            $this->error = "订单不存在";
            return false;
        }

        if ($order['status'] !== 0 || $order['stage'] !== 1) {
            $this->error = '订单状态异常';
            return false;
        }
        $order->stage = 2;
        \think\Db::startTrans();
        $result = $order->save();
        if (!$result) {
            $this->error = $this->getError();
            return false;
        }

        // 写入订单追踪
        $trace = model('product/product_order_trace', 'service')->create($sn, $user_id, 'service.stage.2');
        if (!$trace) {
            \think\Db::rollback();
            $this->error = model('product/product_order_trace', 'service')->getError();
            return false;
        }
        \think\Hook::listen("ProductOrderConfirmAfter", $result);
        \think\Db::commit();
        return $order;
    }


    public function complain($sn, $user_id = false)
    {
        $maps = ['sn' => $sn];
        if ($user_id !== false) {
            $maps['uid'] = $user_id;
        }
        $order = $this->model->where($maps)->find();

        if (!$order) {
            $this->error = "订单不存在";
            return false;
        }

        if ($order['status'] !== 0 || $order['stage'] !== 1) {
            $this->error = '订单状态异常';
            return false;
        }

        if ($order['complain_id']) {
            $this->error = '请等待联系';
            return false;
        }

        \think\Db::startTrans();
        $model_complain = model('product/product_order_complain', 'service');
        $complain = $model_complain->save([
            'order_sn'    => $sn,
            'user_id'     => $order['uid'],
            'customer_id' => $order['customer_id'],
        ]);

        if (!$complain) {
            \think\Db::rollback();
            $this->error = $model_complain->getError();
            return false;
        }

        // 变更订单状态
        $order->complain_id = $complain['id'];
        $result = $order->save($order, ['sn' => $sn]);
        if (!$result) {
            \think\Db::rollback();
            return false;
        }
        \think\Db::commit();
        return $order;
    }

    /**
     * 客户经理推送清单
     * @param string $sn
     * @param array  $profile
     * @param bool   $user_id
     * @return bool
     */
    public function push($sn, $profile = [], $user_id = false)
    {
        if (!$profile) {
            $this->error = "资料不能为空";
            return false;
        }

        $order = $this->model->where(['sn' => $sn])->find();
        if (!$order) {
            $this->error = '订单信息不存在';
            return false;
        }

        if ($order['status'] !== 0 || $order['stage'] !== 2) {
            $this->error = '订单状态异常，请联系管理员';
            return false;
        }
        $product = $order->product;

        \think\Db::startTrans();
        $profile_template = model('product/profile_template', 'service')
            ->create($product['name'], $profile, $product['id'], $user_id);
        if (!$profile_template) {
            \think\Db::rollback();
            $this->error = model('product/profile_template', 'service')->getError();
            return false;
        }

        $info = collection($order)->toArray();
        $order->stage = 3;
        $order->profile_template_id = $profile_template['id'];

        $result = $order->save();
        if (!$result) {
            \think\Db::rollback();
            $this->error = $this->getError();
            return false;
        }
        // 写入订单追踪
        $trace = model('product/product_order_trace', 'service')->create($order['sn'], $order['uid'], 'service.stage.3');
        if (!$trace) {
            \think\Db::rollback();
            $this->error = model('product/product_order_trace', 'service')->getError();
            return false;
        }

        \think\Hook::listen("ProductOrderPushAfter", $result);
        \think\Db::commit();
        return $order;
    }


    /**
     * 客户准备资料清单
     * @param integer $sn      订单编号
     * @param array   $profile 资料合集
     * @return bool
     */
    public function profile($sn, $profile = [])
    {
        $order = $this->model->where(['sn' => $sn])->find();

        if (!$order) {
            $this->error = '订单信息不存在';
            return false;
        }

        if ($order['status'] !== 0 || $order['stage'] !== 3) {
            $this->error = '订单状态异常，请联系管理员';
            return false;
        }

        $profile_template_info = $order->getAttr('profile_template_info');
        $profile_prop = $profile_template_info['profile_prop'];
        $props = [];
        foreach ($profile_prop AS $key => $value) {
            $props[$key] = \fast\ArrayHelper::get_ids_arr($value['value'], 'id');
        }

        $diff = array_udiff_assoc($props, (array)$profile, function ($a, $b) {
            return array_diff($a, $b);
        });

        if ($diff) {
            $this->error = '资料有误';
            return false;
        }

        \think\Db::startTrans();
        $order->stage = 4;

        $result = $order->save();
        if (!$result) {
            \think\Db::rollback();
            $this->error = $this->getError();
            return false;
        }
        // 写入订单追踪
        $trace = model('product/product_order_trace', 'service')->create($order['sn'], $order['uid'], 'service.stage.4');
        if (!$trace) {
            \think\Db::rollback();
            $this->error = model('product/product_order_trace', 'service')->getError();
            return false;
        }

        \think\Hook::listen("ProductOrderProfileAfter", $order);
        \think\Db::commit();
        return $order;
    }

    /**
     * @param string $sn 订单编号
     * @param bool   $user_id
     * @return boolean
     */
    public function research($sn, $user_id = false)
    {
        $maps = ['sn' => $sn];
        $order = $this->model->where($maps)->find();
        if (!$order) {
            $this->error = "订单不存在";
            return false;
        }

        if ($order['status'] !== 0 || $order['stage'] !== 4) {
            $this->error = '订单状态异常';
            return false;
        }
        $order->stage = 5;
        \think\Db::startTrans();
        $result = $order->save();
        if (!$result) {
            $this->error = $this->getError();
            return false;
        }

        // 写入订单追踪
        $trace = model('product/product_order_trace', 'service')->create($sn, $user_id, 'service.stage.5');
        if (!$trace) {
            \think\Db::rollback();
            $this->error = model('product/product_order_trace', 'service')->getError();
            return false;
        }
        \think\Hook::listen("ProductOrderConfirmAfter", $order);
        \think\Db::commit();
        return $order;
    }

    /**
     * 客户经理实调签单&&上报
     * @param string $sn
     * @param bool   $user_id
     * @return bool
     */
    public function submit($sn, $user_id = false)
    {
        $maps = ['sn' => $sn];
//        if($user_id !== false) {
//            $maps['uid'] = $user_id;
//        }
        $order = $this->model->where($maps)->find();

        if (!$order) {
            $this->error = "订单不存在";
            return false;
        }

        if ($order['status'] !== 0 && $order['stage'] !== 5) {
            $this->error = '订单状态异常';
            return false;
        }

        $order->stage = 6;
        \think\Db::startTrans();
        $result = $order->save();
        if (!$result) {
            $this->error = $this->getError();
            return false;
        }

        // 写入订单追踪
        $trace = model('product/product_order_trace', 'service')->create($sn, $user_id, 'service.stage.6');
        if (!$trace) {
            \think\Db::rollback();
            $this->error = model('product/product_order_trace', 'service')->getError();
            return false;
        }
        \think\Hook::listen("ProductOrderSubmitAfter", $order);
        \think\Db::commit();
        return $order;
    }

    /**
     * 贷款审核
     * @param string  $sn    订单号
     * @param integer $stage 阶段
     * @param integer $user_id
     * @return bool
     */
    public function review($sn, $stage = 99, $user_id = 0, $force = false)
    {
        $maps = ['sn' => $sn];
        $order = $this->model->where($maps)->find();

        if (!$order) {
            $this->error = "订单不存在";
            return false;
        }

        if ($order['status'] !== 0) {
            $this->error = '订单状态异常';
            return false;
        }

        if($force === true && $order['stage'] !== 6) {
            $this->error = '订单状态异常';
            return false;
        }

        $order['stage'] = $stage;
        $order['status'] = 1;
        \think\Db::startTrans();
        $result = $order->save();
        if (!$result) {
            $this->error = $this->getError();
            return false;
        }
        // 写入订单追踪
        $trace = model('product/product_order_trace', 'service')->create($sn, $user_id, 'service.stage.' . $stage);
        if (!$trace) {
            \think\Db::rollback();
            $this->error = model('product/product_order_trace', 'service')->getError();
            return false;
        }
        // 发放相关积分
        if ($stage == 99) {
            $user_model = model('user/user', 'service');
            $product = $order->product;
            if ($order['customer_id'] > 0 && $order['customer_point']) {
                $customer_point = $user_model->point($order['customer_id'], $order['customer_point'], 'product', '产品（' . $product['name'] . '）订单奖励', $sn);
                if (!$customer_point) {
                    \think\Db::rollback();
                    $this->error = $user_model->getError();
                    return false;
                }
            }

            if ($order['distributor_id'] > 0 && $order['distributor_point']) {
                $distributor_point = $user_model->point($order['distributor_id'], $order['distributor_point'], 'product', '产品（' . $product['name'] . '）订单奖励', $sn);
                if (!$distributor_point) {
                    \think\Db::rollback();
                    $this->error = $user_model->getError();
                    return false;
                }
            }
        }
        \think\Hook::listen("ProductOrderReviewAfter", $order);
        \think\Db::commit();
        return $order;
    }

}
